/**
 * 
 */
package ChatGUI;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * @author Pierre LUKJANENKO
 *
 */
public class ChatGUI extends JFrame{

	/*
	 *  ATTRIBUTES
	 */
	private StateGUI state;
	private Dimension size = new Dimension(500,300);
	// For Disconnected State (initial state)
	private JTextField username;
	private JButton bConnection;
	protected JPanel rpDisconnected;
	// For Connected State
	protected JLabel message;
	private JButton bDisconnection;
	protected JPanel rpConnected;
	private JLabel errorNotif;
	
	
	
	/*
	 *  CONSTRUCTOR
	 */
	/**
	 * Constructor of ChatGUI class
	 */
	public ChatGUI() {
		this.setGUIState(new DisconnectedGUI());
		initComponents();
		state.loadView(this);
		this.setVisible(true);
	}
	
	
	
	/*
	 *  SETTERS & GETTERS
	 */
	/**
	 * @param newState
	 * Sets the state's value to the value of newState
	 */
	protected void setGUIState(StateGUI newState) {
		this.state = newState;
	}
	/**
	 * @return this.state
	 * Returns the value of state attribute
	 */
	protected StateGUI getGUIState() {
		return this.state;
	}
	
	
	
	/*
	 * COMPONENTS INITIALISATION
	 */
	private void initComponents() {
		// Window characteristics
		this.setSize(size);
		this.setTitle("Chat System");
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		// For Disconnected State (initial state)
		username = new JTextField("Enter a username");
		username.setMinimumSize(new Dimension(20,20));
		bConnection = new JButton("Connection");
		bConnection.addActionListener(new ConnectionClick(this));
		errorNotif = new JLabel("");
		errorNotif.setVisible(false);
		rpDisconnected = new JPanel();
		rpDisconnected.setSize(size);
		rpDisconnected.add(username);
		rpDisconnected.add(bConnection);
		rpDisconnected.add(errorNotif);
		this.add(rpDisconnected);
		rpDisconnected.setVisible(false);
		// For Connected State
		message = new JLabel("OOPS : not connected !");
		bDisconnection = new JButton("Disconnection");
		bDisconnection.addActionListener(new DisconnectionClick(this));
		rpConnected = new JPanel();
		rpConnected.add(message);
		rpConnected.add(bDisconnection);
		rpConnected.setVisible(false);
		this.add(rpConnected);
	}
	
	
	
	/*
	 * ACTION LISTENERS
	 */
	class ConnectionClick implements ActionListener {
		private ChatGUI chatGUILoopback;
		private class UsernameEmptyException extends Exception{}
		private class CharacterNotAcceptedException extends Exception{}
		
		// CONSTRUCTOR
		public ConnectionClick(ChatGUI gui) {
			this.chatGUILoopback = gui;
		}
		@Override
		public void actionPerformed(ActionEvent arg0) {
			String name = username.getText();
			errorNotif.setVisible(false);
			try {
				name = correctUsername(name);
				message.setText("You're now connected as " + name + ".");
				state.changeState(chatGUILoopback);
				state.loadView(chatGUILoopback);
				chatGUILoopback.setVisible(true);
			} catch (UsernameEmptyException ue) {
				errorNotif.setText("Your username cannot be empty !");
				errorNotif.setVisible(true);
			} catch (CharacterNotAcceptedException cnae) {
				errorNotif.setText("Your username cannot contain :  \" nor \\ nor '");
				errorNotif.setVisible(true);
			}
			
		}
		private String correctUsername(String name) throws UsernameEmptyException, CharacterNotAcceptedException {
			String username = name.replaceAll(" ", "_");
			if (username.equals("")) {
				throw new UsernameEmptyException();
			}
			if (username.contains("\"") || username.contains("\\") || username.contains("'")) {
				throw new CharacterNotAcceptedException();
			}
			return username;
		}
	}
	
	class DisconnectionClick implements ActionListener {
		ChatGUI chatGUILoopback;
		// CONSTRUCTOR
		public DisconnectionClick(ChatGUI gui) {
			this.chatGUILoopback = gui;
		}
		@Override
		public void actionPerformed(ActionEvent arg0) {
			//message.setText(username.getText()+" is now disconnected.");
			chatGUILoopback.username.setText("Enter a username");
			state.changeState(chatGUILoopback);
			state.loadView(chatGUILoopback);
			chatGUILoopback.setVisible(true);
		}
	}
}
